Skip to content

Implemented the retry policy engine - #405

Merged
Lakes41 merged 4 commits into
Adamantine-guild:mainfrom
El-swaggerito:implemented-the-retry-policy-engine-
Aug 30, 2026
Merged

Implemented the retry policy engine #405
Lakes41 merged 4 commits into
Adamantine-guild:mainfrom
El-swaggerito:implemented-the-retry-policy-engine-

Conversation

@El-swaggerito

Copy link
Copy Markdown
Contributor

Description

Implemented a generic asynchronous retry engine for GuildPass Core that provides configurable exponential backoff, jitter, cancellation, and caller-defined retry classification. This standalone resilience primitive can be adopted by future integrations (Stellar RPC, internal services, event processors) without depending on those services today.

Linked Issue

Closes #370

Type of Change

  • ✨ New feature / endpoint

Changes Made

  • Created new package: @guildpass/retry-policy - A standalone retry engine with no dependencies on Stellar RPC, HTTP clients, Redis, Prisma, or other services
  • Implemented retry configuration: RetryOptions interface with maxAttempts, initialDelay, maxDelay, backoffMultiplier, jitter config, AbortSignal, isRetryable predicate, and onRetry callback
  • Built exponential backoff: calculateBackoff() function with configurable multiplier, max delay capping, and full jitter support
  • Implemented main retry function: retry() with attempt counting, retry classification, error preservation via RetryExhaustedError, and cancellation support
  • Added timer cleanup: Proper cleanup of timers on success, failure, cancellation, and non-retryable errors
  • Created utility functions: retryableByType(), retryableByCode(), retryableIf() for common retry classification patterns
  • Wrote comprehensive tests: 48 unit tests covering backoff calculation, success/failure scenarios, exponential backoff timing, jitter behavior, cancellation, callbacks, validation, utility functions, edge cases, and timer cleanup

Test Evidence

pnpm --filter @guildpass/retry-policy test

Output:

✔ Retry Policy Engine (26322.700231ms)
ℹ tests 48
ℹ suites 16
ℹ pass 48
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 26526.252769

Smart Contract Checklist (complete if ⛓️ checked above)

N/A - This is a TypeScript package, not a smart contract

General Checklist

  • I have read CONTRIBUTING.md
  • This PR is linked to an open issue
  • npm run typecheck passes (or pnpm typecheck)
  • npm run lint passes (N/A - no linting configured for this package)
  • npm run test passes — all tests green (or pnpm test)
  • Prisma schema changes include a migration file (N/A - no database changes)
  • New API endpoints are documented in OpenAPI (N/A - this is a library package, not an API)
  • No secrets, keys, or wallet addresses introduced
  • .env.example updated if new env variables were added (N/A - no env variables)
  • Documentation updated if new behaviour was introduced (comprehensive JSDoc comments in source)

Additional Notes

  • Independence: This package is independently implementable and does not depend on Stellar RPC, HTTP clients, Redis, Prisma, or other services
  • No external dependencies: Pure TypeScript implementation using only standard Web APIs (AbortSignal, setTimeout)
  • Side-effect free: Proper timer cleanup on all code paths (success, failure, cancellation, non-retryable errors)
  • TypeScript strict mode: Full type safety with comprehensive interfaces
  • Deterministic jitter: Supports injectable random source for deterministic testing
  • First attempt counted: The first execution is counted as attempt 1, not attempt 0
  • Error preservation: RetryExhaustedError preserves the original error as cause and includes attempt count

@Lakes41
Lakes41 merged commit fa834c5 into Adamantine-guild:main Aug 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build a resilient retry policy engine with exponential backoff and jitter

2 participants